﻿namespace ScrumLite.WebUx.Tests
{
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using ScrumLite.Services;
    using ScrumLite.WebUx.Controllers;
    using ScrumLite.WebUx.Models;
    using ScrumLite.Services.Contracts;
    using System;
    using System.Configuration;
    using System.Security.Permissions;
    using System.Globalization;
    using System.Web.Mvc;

    /// <summary>
    /// Summary description for WorkAreaControllerFixture
    /// </summary>
    [TestClass]
    public class WorkAreaControllerFixture
    {
        [TestMethod]
        public void ShouldShowWeightGroupedByWorkArea()
        {
            MockRequestsService service = new MockRequestsService();
            TestableWorkAreaController controller = new TestableWorkAreaController(service);

            controller.List(MockHelpers.KnownProjectId.ToString());

            WorkAreasListViewData dataShown = (WorkAreasListViewData)controller.DataToShow;
            Assert.IsNotNull(controller.DataToShow);
            Assert.IsInstanceOfType(controller.DataToShow, typeof(WorkAreasListViewData));
            Assert.AreEqual(3, dataShown.WorkAreas.Count);
            Assert.AreEqual("Site Admin Tool", dataShown.WorkAreas[0].Name);
            Assert.AreEqual(23, dataShown.WorkAreas[0].Weight);
            Assert.IsNotNull(((WorkAreasListViewData)controller.DataToShow).ProjectId);
            Assert.IsNotNull(((WorkAreasListViewData)controller.DataToShow).ProjectName);

        }

        [TestMethod]
        public void ShouldSaveAWorkArea()
        {
            MockRequestsService service = new MockRequestsService();
            TestableWorkAreaController controller = new TestableWorkAreaController(service);

            string projectId = "AF06A611-12CE-4C06-B3AD-E2754D12D516";
            string name = "Site Admin Tool";
            Guid id = new Guid("BB184E41-B84D-4c2f-9251-CB0F8E8D7DDB");
            controller.Save(projectId, name, id.ToString());

            WorkArea workArea = service.GetWorkArea(projectId, id);

            Assert.IsNotNull(workArea);
            Assert.AreEqual(workArea.Name, name);
            Assert.AreNotEqual(workArea.Name, "pepe");
        }

        [TestMethod]
        public void ShouldRenderEditAWorkArea()
        {
            MockRequestsService service = new MockRequestsService();
            TestableWorkAreaController controller = new TestableWorkAreaController(service);

            string projectId = "AF06A611-12CE-4C06-B3AD-E2754D12D516", name = "";
            string id = Guid.NewGuid().ToString();
            controller.Edit(projectId, name, id);

            Assert.IsNotNull(controller.ViewData);
            Assert.AreEqual("Edit", controller.ViewToShow);
            Assert.IsInstanceOfType(controller.DataToShow, typeof(WorkAreaViewData));
            Assert.AreEqual(name, ((WorkAreaViewData)controller.DataToShow).Name);
            Assert.IsNotNull(((ContextViewData)controller.DataToShow).ProjectId);
            Assert.IsNotNull(((ContextViewData)controller.DataToShow).ProjectName);
        }

        [TestMethod]
        public void ShouldShowDeliverablesCount()
        {
            MockRequestsService service = new MockRequestsService();
            TestableWorkAreaController controller = new TestableWorkAreaController(service);

            controller.List(MockHelpers.KnownProjectId.ToString());

            WorkAreasListViewData dataShown = (WorkAreasListViewData)controller.DataToShow;
            Assert.IsNotNull(controller.DataToShow);
            Assert.IsInstanceOfType(controller.DataToShow, typeof(WorkAreasListViewData));
            Assert.AreEqual(3, dataShown.WorkAreas.Count);
            Assert.AreEqual("Site Admin Tool", dataShown.WorkAreas[0].Name);
            Assert.AreEqual(23, dataShown.WorkAreas[0].Weight);
            Assert.AreEqual(3, dataShown.WorkAreas[0].Deliverables);
            Assert.IsNotNull(((ContextViewData)controller.DataToShow).ProjectId);
            Assert.IsNotNull(((ContextViewData)controller.DataToShow).ProjectName);
        }

        [TestMethod]
        public void ShouldShowRequestCount()
        {
            MockRequestsService service = new MockRequestsService();
            TestableWorkAreaController controller = new TestableWorkAreaController(service);

            controller.List(MockHelpers.KnownProjectId.ToString());

            WorkAreasListViewData dataShown = (WorkAreasListViewData)controller.DataToShow;
            Assert.IsNotNull(controller.DataToShow);
            Assert.IsInstanceOfType(controller.DataToShow, typeof(WorkAreasListViewData));
            Assert.AreEqual(3, dataShown.WorkAreas.Count);
            Assert.AreEqual("Site Admin Tool", dataShown.WorkAreas[0].Name);
            Assert.AreEqual(23, dataShown.WorkAreas[0].Weight);
            Assert.AreEqual(3, dataShown.WorkAreas[0].Deliverables);
            Assert.AreEqual(8, dataShown.WorkAreas[0].Requests);
            Assert.IsNotNull(((ContextViewData)controller.DataToShow).ProjectId);
            Assert.IsNotNull(((ContextViewData)controller.DataToShow).ProjectName);
        }

        [TestMethod]
        public void ShouldRenderWorkAreasMetricsWithData()
        {
            string mockProjectUri = Guid.NewGuid().ToString();
            MockRequestsService service = new MockRequestsService();
            TestableWorkAreaController controller = new TestableWorkAreaController(service);

            controller.WorkAreasMetrics(mockProjectUri);

            Assert.AreEqual("WorkAreasMetrics", controller.ViewToShow);
            Assert.IsInstanceOfType(controller.DataToShow, typeof(WorkAreasMetricsData));
            Assert.IsInstanceOfType(controller.DataToShow, typeof(ContextViewData));
            Assert.IsNotNull(((ContextViewData)controller.DataToShow).ProjectId);
            Assert.IsNotNull(((ContextViewData)controller.DataToShow).ProjectName);
        }

        [TestMethod]
        public void ShouldCallGetWorkAreasGroupByWeightOnRenderWorkAreasMetricsView()
        {
            string mockProjectUri = Guid.NewGuid().ToString();
            MockRequestsService requestsService = new MockRequestsService();
            requestsService.GetWorkAreasGroupByWeightCalled = false;
            TestableWorkAreaController controller = new TestableWorkAreaController(requestsService);

            controller.WorkAreasMetrics(mockProjectUri);

            Assert.IsTrue(requestsService.GetWorkAreasGroupByWeightCalled);
            Assert.IsNotNull(((WorkAreasMetricsData)controller.DataToShow).WorkAreasByWeight);
            Assert.AreEqual(3, ((WorkAreasMetricsData)controller.DataToShow).WorkAreasByWeight.Count);
            Assert.IsNotNull(((ContextViewData)controller.DataToShow).ProjectId);
            Assert.IsNotNull(((ContextViewData)controller.DataToShow).ProjectName);
        }

        [TestMethod]
        public void ShouldGenerateWorkAreasMetricsPieUrl()
        {
            string mockProjectUri = Guid.NewGuid().ToString();
            MockRequestsService requestsService = new MockRequestsService();
            TestableWorkAreaController controller = new TestableWorkAreaController(requestsService);

            controller.WorkAreasMetrics(mockProjectUri);

            string expectedByWeightUrl = @"http://chart.apis.google.com/chart?cht=p3&chs=400x150&chd=t:23.0,65.0,34.0&chtt=Weight+by+workarea&chl=Site%20Admin%20Tool%20(23)|Modularity%20(65)|Management%20(34)";
            string expectedByRequestUrl = @"http://chart.apis.google.com/chart?cht=p3&chs=400x150&chd=t:8.0,12.0,32.0&chtt=Request+by+workarea&chl=Site%20Admin%20Tool%20(8)|Modularity%20(12)|Management%20(32)";
            Assert.AreEqual(expectedByWeightUrl, ((WorkAreasMetricsData)controller.DataToShow).GChartWorkAreasByWeightPie);
            Assert.AreEqual(expectedByRequestUrl, ((WorkAreasMetricsData)controller.DataToShow).GChartWorkAreasByRequestPie);
            Assert.IsNotNull(((ContextViewData)controller.DataToShow).ProjectId);
            Assert.IsNotNull(((ContextViewData)controller.DataToShow).ProjectName);
        }

        [TestMethod]
        public void ShouldGenerateEmptyWorkAreasMetricsPieUrl()
        {
            string mockProjectUri = MockRequestsService.ProjectIdForEmptyData;
            MockRequestsService requestsService = new MockRequestsService();
            TestableWorkAreaController controller = new TestableWorkAreaController(requestsService);

            controller.WorkAreasMetrics(mockProjectUri);

            string expectedUrl1 = String.Format(CultureInfo.InvariantCulture,"/{0}/{1}", ConfigurationManager.AppSettings["SiteImagesPath"], "chart_EmptyRequestByWorkAreaPie.png");
            string expectedUrl2 = String.Format(CultureInfo.InvariantCulture,"/{0}/{1}", ConfigurationManager.AppSettings["SiteImagesPath"], "chart_EmptyWeightByWorkAreaPie.png");
            Assert.AreEqual(expectedUrl1, ((WorkAreasMetricsData)controller.DataToShow).GChartWorkAreasByRequestPie);
            Assert.AreEqual(expectedUrl2, ((WorkAreasMetricsData)controller.DataToShow).GChartWorkAreasByWeightPie);
        }
    }

    public class TestableWorkAreaController : WorkAreasController
    {
        public object DataToShow { get; set; }
        public object ViewToShow { get; set; }

        public TestableWorkAreaController(IRequestsService service)
        : this(service, new MockProjectsService(), new MockProfileService())
        { }

        public TestableWorkAreaController(IRequestsService request, IProjectsService project, IProfileService profile)
            : base(request, project, profile)
        {
        }

        protected override void RedirectToAction(object values)
        {
        }

        [SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)]
        protected override void RenderView(string viewName, string masterName, object viewData)
        {
            ViewToShow = viewName;
            DataToShow = viewData;
        }       
    }      
}
